/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package elaborate.h2x.parser;

import elaborate.h2x.transform.DefaultRelationImpl;
import elaborate.h2x.transform.RelationType;
import elaborate.h2x.transform.TransformingModel;
import elaborate.h2x.transform.TransformingNode;
import elaborate.h2x.transform.TransformingNodeId;
import elaborate.h2x.transform.service.Locator;
import elaborate.h2x.transform.service.Services;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;

/**
 *
 * @author lendle
 */
public class DefaultRelationFactoryImpl implements RelationFactory{

    public void createRelation(Services services, TransformingModel model, TransformingNode node) throws ParserException {
        Element element=(Element) node.getOriginalNode();
        Attr relationAttr = element.getAttributeNodeNS("h2x", "relation");
        String relationAttrValue=relationAttr.getValue();
        if(relationAttrValue==null || relationAttrValue.length()==0){
            throw new ParserException("empty relation setting");
        }
        String [] relations=relationAttrValue.split(";");
        if(relations==null || relations.length==0){
            throw new ParserException("empty relation setting");
        }

        for(String relation_exp : relations){
            String [] relationDetail=relation_exp.split(",");
            DefaultRelationImpl relation=new DefaultRelationImpl();
            if(relationDetail.length==3){
                this.parse(relationDetail[0], relationDetail[1], relationDetail[2], services, model, node, relation);
            }else if(relationDetail.length==1){
                this.parse(relationDetail[0], services, model, node, relation);
            }else{
                throw new ParserException("wrong argument number for relation setting: must be 3 or 1");
            }
        }
    }

    protected void parse(String context_exp, String target_exp, String relation_type_exp, Services services, TransformingModel model, TransformingNode node, DefaultRelationImpl relation)throws ParserException{
        Locator locator=services.getLocator();
        TransformingNode contextNode=locator.locateNode(model, node, context_exp);
        TransformingNode targetNode=locator.locateNode(model, node, target_exp);
        if(contextNode==null){
            throw new ParserException("cannot locate contextNode: "+context_exp);
        }
        if(targetNode==null){
            throw new ParserException("cannot locate targetNode: "+target_exp);
        }
        this.parse(
                contextNode.getId(),
                targetNode.getId(),
                relation_type_exp,
                services,
                model,
                node,
                relation);
    }

    protected void parse(String relation_type_exp, Services services, TransformingModel model, TransformingNode node, DefaultRelationImpl relation)throws ParserException{
        this.parse(
                model.getNearestEnclosingNode(node).getId(),
                node.getId(),
                relation_type_exp,
                services,
                model,
                node,
                relation);
    }

    protected void parse(TransformingNodeId context, TransformingNodeId target, String relation_type_exp, Services services, TransformingModel model, TransformingNode node, DefaultRelationImpl relation)throws ParserException{
        relation.setContext(context);
        relation.setTarget(target);
        if("child".equals(relation_type_exp)){
            relation.setRelationType(RelationType.CHILD);
        }else if("next".equals(relation_type_exp)){
            relation.setRelationType(RelationType.NEXT);
        }
        model.getNode(target).getRelationList().add(relation);
        //System.out.println("context="+relation.getContext()+", target="+relation.getTarget()+", relationType="+relation.getRelationType());
    }
}
